package cn.juque.lucenecandy.core.datasync.listener;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.juque.common.constants.NumberConstant;
import cn.juque.common.utils.CommonBooleanUtil;
import cn.juque.lucenecandy.core.base.BaseMessageEntity;
import cn.juque.lucenecandy.core.constants.StrConstant;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author juque
 * @version 1.0.0
 * <ul>
 *     <li>MsgWriteListener</li>
 * </ul>
 * @date 2024-02-02
 **/
@Component("msgWriteListenerRender")
public class MsgWriteListenerRender {

    private static final List<IMsgWriteListener> MSG_LISTENERS = new ArrayList<>();

    /**
     * 初始化
     */
    public void init() {
        Map<String, IMsgWriteListener> listenerMap = SpringUtil.getBeansOfType(IMsgWriteListener.class);
        if (MapUtil.isEmpty(listenerMap)) {
            return;
        }
        List<IMsgWriteListener> list = CollUtil.newArrayList(listenerMap.values());
        list = list.stream().sorted(Comparator.comparing(c -> {
            Object value = AnnotationUtil.getAnnotationValue(c.getClass(), Order.class, StrConstant.VALUE);
            return Objects.isNull(value) ? NumberConstant.ONE_THOUSAND : (Integer) value;
        })).collect(Collectors.toList());
        CollUtil.addAll(MSG_LISTENERS, list);
    }

    /**
     * 执行事前操作
     *
     * @param param 参数
     * @return boolean
     */
    public boolean before(BaseMessageEntity param) {
        boolean flag = true;
        for (IMsgWriteListener msgWriteListener : MSG_LISTENERS) {
            flag = msgWriteListener.before(param);
            if (CommonBooleanUtil.isFalse(flag)) {
                break;
            }
        }
        return flag;
    }

    /**
     * 事后操作
     *
     * @param param IndexUpdateParamVO
     */
    public void after(BaseMessageEntity param) {
        MSG_LISTENERS.forEach(f -> f.after(param));
    }
}
